package com.open.capacity.finance.service;

import com.open.capacity.finance.constant.AuditWarnStatus;
import com.open.capacity.finance.dao.AuditModelWarnScopeDao;
import com.open.capacity.finance.dto.AuditModelBaseResult;
import com.open.capacity.finance.entity.AuditModel;
import com.open.capacity.finance.entity.AuditModelWarn;
import com.open.capacity.finance.entity.AuditModelWarnLog;
import com.open.capacity.user.service.SysUserRelationService;
import com.open.capacity.user.service.SysUserService;
import javafx.util.Pair;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.task.TaskExecutor;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.concurrent.CompletableFuture;

@Slf4j
public abstract class AbstractAuditMakeResultFactory<T extends AuditModelBaseResult> {


    @Value("${file.uploadpath:/usr/local/files/upload}")
    public String fileuploadPath;

    @Autowired
    private AuditModelWarnLogService warnLogService;

    @Autowired
    private AuditModelWarnScopeDao warnScopeDao;

    @Autowired
    private AuditModelWarnService warnService;

    @Autowired
    private SysUserService userService;

    @Autowired
    private SysUserRelationService relationService;

    @Autowired
    private TaskExecutor taskExecutor;


    public void run(AuditModel model, String companyId, Map<String, Object> param) {
        int excuteResult = 1;
        String resultUrl = null;
        String modelId = model.getId();

        try {
            param.put("companyId", companyId);
            param.put("kjnd", model.getDefaultKjnd());
            AuditModelBaseResult data = analyseResultData(modelId, param);
            if (data.getExists().equals(1)) {
                resultUrl = data.getResultFileUrl();
                AuditModelWarn lastWarn = warnService.findLastByModelId(modelId, companyId, null);
                //忽略结果集相同的告警
                if (lastWarn == null || !data.getResultFileMd5().equals(lastWarn.getResultMd5())) {
                    AuditModelWarn warn = new AuditModelWarn();
                    warn.setModelId(modelId);
                    warn.setModelName(model.getCode() + " " + model.getName());
                    warn.setWarnLevel(data.getExists());
                    warn.setResultMd5(data.getResultFileMd5());
                    warn.setResultUrl(data.getResultFileUrl());
                    warn.setDealFlag(0);
                    warn.setCreateTime(new Date());
                    warn.setCompanyId(companyId);
                    warn.setStatus(AuditWarnStatus.NEW.getCode());
                    warnService.save(warn);
                }
            }

            //异步将离线文件写入数据库
            int finalExcuteResult = excuteResult;
            String finalResultUrl = resultUrl;
            CompletableFuture.runAsync(() -> {
                AuditModelWarnLog log = new AuditModelWarnLog();
                log.setModelId(modelId);
                log.setCompanyId(companyId);
                log.setModelName(model.getCode() + " " + model.getName());
                log.setResultUrl(finalResultUrl);
                log.setExcuteResult(finalExcuteResult);
                log.setCreateTime(new Date());
                warnLogService.save(log);
            }, taskExecutor);

        } catch (Exception e) {
            log.error(e.toString());
            excuteResult = -1;
        }


    }

    /**
     * 分析结果集
     *
     * @return
     */
    protected abstract T analyseResultData(String modelId, Map<String, Object> param);

    /**
     * 持久化结果集
     *
     * @return
     */
    protected abstract int persistence(T data);

    /**
     * 访问结果集
     *
     * @return
     */
    public abstract T getData(String modelId, Map<String, Object> param);


    /**
     * 访问结果集
     *
     * @return
     */
    public abstract T getDataFromJson(String jsonUrl, Map<String, Object> param);

    /**
     * 导出excel
     */
    public abstract void exportExcel(String modelId, Map<String, Object> params, HttpServletResponse response);

    /**
     * 导出excel
     */
    public abstract void exportExcelFromJson(String modelId, String jsonUrl, HttpServletResponse response);

}
